package auditoryUI;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Random;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.filechooser.FileNameExtensionFilter;

public class SimpleExperimentManager {

	private SimpleDriver sd;

	private SimpleUI display;

	private JFrame trialFrame;

	private JList trialList;

	private final String filePath = "./Trials/";

	private int status = Constants.STATUS_END;

	private Trial currentTrial;

	private int userID = -1;

	private Logger log;

	private Vector<Trial> trials;

	private JProgressBar progress;

	private int size = -1;

	public SimpleExperimentManager(SimpleDriver sd) {
		this.sd = sd;
		display = sd.getDisplay();
		trialFrame = new JFrame("Trials");
		progress = new JProgressBar(0, 40);
		progress.setStringPainted(true);

		JPanel panel = new JPanel();

		JButton load = new JButton("load");
		JButton start = new JButton("Start");
		JButton open = new JButton("open");

		panel.add(load, BorderLayout.LINE_START);
		panel.add(start, BorderLayout.CENTER);
		// panel.add(open,BorderLayout.LINE_END);

		trialFrame.getContentPane().add(panel, BorderLayout.SOUTH);
		trialFrame.getContentPane().add(progress, BorderLayout.NORTH);
		load.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				loadConfigurationFile();
			}
		});

		start.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				startTrial();
			}
		});

		// trialFrame.getContentPane().add(button1,BorderLayout.SOUTH);
		trialFrame.setVisible(true);
		trialFrame.setSize(350, 100);
		trialFrame.setResizable(false);
		log = new Logger();

	}

	public void setLocation(int x, int y) {
		trialFrame.setLocation(x, y);
	}

	private void startTrial() {
		getUserID();
		log.setCondition(sd.getConfiguration());
		TrialCarrier tc = new TrialCarrier(progress);
		tc.start();
	}

	public void userStart() {
		if (currentTrial == null){
			return;
		}
		currentTrial.reactionTime =  System.currentTimeMillis();
		log.setUserID(userID);
		status = Constants.STATUS_START;
		//display.hideGoal();
	}

	public int getStatus() {
		return status;
	}

	public void hasReachedGoal(String goal) {
		if (status == Constants.STATUS_START) {
			currentTrial.completeTime = System.currentTimeMillis();
			if (currentTrial.goal.equals(goal)) {
				status = Constants.STATUS_END;
				//display.showMessage("Accomplished");
				currentTrial.done = true;
				log.logHighLevel(userID, currentTrial.reactionTime - currentTrial.stimulusPlayTime,
						currentTrial.completeTime - currentTrial.reactionTime,
						"O");
				sd.reset();
				synchronized (currentTrial) {
					try {
						currentTrial.notify();
					} catch (Exception e) {
					}
				}
			} else {
				log.logHighLevel(userID,currentTrial.reactionTime -  currentTrial.stimulusPlayTime,
						currentTrial.completeTime - currentTrial.reactionTime,
						"X");
				currentTrial.reset();
				display.showGoal("Again, " + currentTrial.goal);
				currentTrial.stimulusPlayTime =  System.currentTimeMillis();
				status = Constants.STATUS_STANDBY;
				sd.reset();
			}
		}
	}

	public void logUserAction(String actionType, String item,
			int x, int y, int z) {
		if (status == Constants.STATUS_START) {
			String stat = "";
			if (status == Constants.STATUS_START) {
				stat = "in progress";
			} else if (status == Constants.STATUS_END) {
				stat = "trial ends";
			}
			log.log(sd.getConfiguration(), actionType, item, stat,
					currentTrial.goal, x, y, z);
		}
	}

	public String getUserID() {
		if (userID == -1) {
			String text = JOptionPane.showInputDialog(display, "user id");
			try {
				userID = Integer.parseInt(text);
			} catch (Exception e) {
				getUserID();
			}
		}
		return userID + "";
	}

	private void loadConfigurationFile() {
		JFileChooser jc = new JFileChooser(System.getProperty("user.dir")
				+ "/Trials");
		File f = null;
		FileNameExtensionFilter filter = new FileNameExtensionFilter(
				"configuration file", "txt");
		jc.setFileFilter(filter);
		int returnVal = jc.showOpenDialog(trialFrame);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			f = jc.getSelectedFile();
		} else {
			return;
		}
		log.setTrialFileName(f.getName());
		parseFile(f.getAbsolutePath());

	}

	private void parseFile(String path) {
		Vector<Trial> tmp = new Vector<Trial>();
		try {
			FileReader fr = new FileReader(path);
			BufferedReader br = new BufferedReader(fr);
			String goal = br.readLine();
			size = Integer.parseInt(goal);
			progress.setMaximum(size);
			goal = br.readLine();
			while (goal != null) {
				if (goal.charAt(0) == '#') {
					Trial tc = new Trial();
					tc.goal = goal.substring(1);
					tmp.add(tc);
				}
				goal = br.readLine();
			}
			br.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		randomizeGoals(tmp);
	}

	private void randomizeGoals(Vector<Trial> in) {
		Random r = new Random();
		int len = size / 4;
		trials = new Vector<Trial>(size);
		trials.addAll(in);
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < len; j++) {
				int a = r.nextInt(len);
				in.add(0, in.get(a));
				in.remove(a + 1);
			}
			trials.addAll(in);
		}
		// for (Trial t : trials){
		// System.out.println(t.goal);
		// }
	}

	private class Trial {
		private String goal = "";

		private String sound = "";

		private boolean done = false;

		private long stimulusPlayTime = -1;
		private long reactionTime = -1;
		private long completeTime = -1;

		public void reset() {
			stimulusPlayTime = -1;
			reactionTime = -1;
			completeTime = -1;
		}
	}

	private class TrialCarrier extends Thread {

		private JProgressBar progress;

		private TrialCarrier(JProgressBar progress) {
			this.progress = progress;
		}

		@Override
		public void run() {
			int count = 0;
			for (Trial t : trials) {
				count++;
				log.setTrialNum(count);
				log.setBlockNum((count-1) / (size / 4));
				progress.setValue(count);
				progress.setString(count + "/" + progress.getMaximum());
				currentTrial = t;
				display.showGoal("Your goal is: " + currentTrial.goal);
				currentTrial.stimulusPlayTime =  System.currentTimeMillis();
				status = Constants.STATUS_STANDBY;
				synchronized (currentTrial) {
					try {
						currentTrial.wait();
					} catch (Exception e) {

					}
				}
			}
			// end of the experiment
			status = Constants.STATUS_END;
		}
	}
}
